//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Internals;

namespace OpenLS.Spreadsheet
{
    ///<summary>
    /// Represents a collection of columns in a worksheet
    ///</summary>
    public partial class ColumnCollection : DimensionCollection<Column>, IOfficeXmlSerializable
    {
        internal ColumnCollection(Worksheet worksheet)
            : base(worksheet)
        {
            
        }

        internal override int MaxIndex
        {
            get { return Worksheet.MaxColumnIndex; }
        }

        protected override double DefaultLength
        {
            get { return Worksheet.DefaultColumnWidth; }
        }

        
            
        


        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            foreach (Column column in this)
            {
                if (column.IsCustom)
                    goto label;
            }
            return;
        label:
            using (WriteContext c = context.Write("cols"))
            {
                Column previousColumn = null;
                Column firstColumn = null;
                foreach (Column column in Enumerable.Where(this, col_ => col_.IsCustom))
                {
                    if (previousColumn != null)
                    {
                        if (previousColumn.Index == column.Index - 1 &&
                            (previousColumn.IsEquivalent(column)))
                        {
                            previousColumn = column;
                            continue;
                        }
                        else
                        {
                            WriteColumnSegment(c, firstColumn, previousColumn);
                            firstColumn = column;
                            previousColumn = column;
                        }
                    }
                    else
                    {
                        firstColumn = column;
                        previousColumn = column;
                    }
                }
                if (firstColumn != null)
                {
                    WriteColumnSegment(c, firstColumn, previousColumn);
                }
            }
        }

        internal IEnumerable<Pair<Column, Column>> GetColumnSegments()
        {
            foreach (Column column in this)
            {
                if (column.IsCustom)
                    goto label;
            }
            yield break;
            label:
            Column previousColumn = null;
            Column firstColumn = null;
            foreach (Column column in Enumerable.Where(this, col => col.IsCustom))
            {
                if (previousColumn != null)
                {
                    if (previousColumn.Index == column.Index - 1 &&
                        (previousColumn.IsEquivalent(column)))
                    {
                        previousColumn = column;
                        continue;
                    }
                    else
                    {
                        yield return new Pair<Column, Column>(firstColumn, previousColumn);
                        firstColumn = column;
                        previousColumn = column;
                    }
                }
                else
                {
                    firstColumn = column;
                    previousColumn = column;
                }
            }

            if (firstColumn != null)
            {
                yield return new Pair<Column, Column>(firstColumn, previousColumn);
            }
        }

        private static void WriteColumnSegment(WriteContext c, Column column1, Column column2)
        {
            using (WriteContext colE = c.Write("col"))
            {
                colE.SetInteger("min", (column1.Index + 1));
                colE.SetInteger("max", (column2.Index + 1));
                column1.WriteAttributes(colE);
            }
        }

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            StyleRecordManager styleRecordManager = context.GetData<StyleRecordManager>();
            Contract.Assert(styleRecordManager != null);
            using (ReadContext c0 = context.Read("cols"))
            {
                using (this.Worksheet.CreateWorksheetPanesDisabler())
                {
                    GroupBuilderStack<Column> stack = new GroupBuilderStack<Column>(
                    this.Worksheet.RootColumnGroup, 
                    (parent, first, last)=>ColumnGroup.CreateColumnGroupWithLast(parent, (Column) first, (Column) last));
                    while (c0.ReaderLocalName == "col")
                    {
                        using (ReadContext c = context.Read("col"))
                        {
                            Column.ColumnGroupRead r = new Column.ColumnGroupRead();
                            r.ReadAttributes(context, stack, styleRecordManager);
                            r.Apply(this, stack);
                            //int min = context.GetInteger("min");
                            // int max = context.GetInteger("max");
                            // for (int i = min; i <= max; i++)
                            {
                                //      Column column = this[i - 1];
                                //      column.ReadAttributes(c, stack, styleRecordManager);
                                //\\this.Add(column);
                            }
                        }
                    }
                    stack.Close();
                }
            }
        }


        internal bool HasIndex(int index)
        {
            return _data.ContainsKey(index);
        }


        internal void ReadXml(ReadContext c)
        {
            IOfficeXmlSerializable s = this;
            s.ReadXml(c);
        }
    }
}
